#include <iostream>

using namespace std;

class MyException {
public:
    virtual void what(void) { cout << "This is a MyException" << endl; }
};

class MySubException : public MyException {
public:
    void what(void) { cout << "This is a MySubException" << endl; }
};

void C(int i) throw(int, double){
    int a = 1;
    double b = 1.2;
    float c = 1.3;
    if (i == 0) {
        cout << "In C, it is OK" << endl;
    } else if (i == 1) {
        throw a;
    } else if (i == 3) {
        throw MyException();
    } else if (i == 4) {
        throw MySubException();
    }
};

void B(int i) {
    cout << "call C" << endl;
    C(i);
    cout << "After call C" << endl;
}

void A(int i) {
    try {
        B(i);
    } catch (int j) {
        cout << "catch exception: " << j << endl;
//    } catch (MySubException &e) {
//        e.what();
    } catch (MyException &e) {
        e.what();
    } catch (...) {
        cout << "catch other..." << endl;
    }
}

void my_unexpected_func() {
    cout << "my_unexpected_func" << endl;
}

void my_terminate_func() {
    cout << "my_terminate_func" << endl;
}

int main() {
    set_unexpected(my_unexpected_func);
    set_terminate(my_terminate_func);

//    A(0);
//    A(0);
//    A(3);
    A(4);

    return 0;
}
